/**
 * Copyright (C) 2017 - 2020 https://github.com/joewee
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.bifrost.web.controller;

import com.alibaba.fastjson.JSONObject;
import com.bifrost.annotation.Authorization;
import com.bifrost.annotation.CurrentStore;
import com.bifrost.annotation.CurrentUser;
import com.bifrost.common.base.ServerResponse;
import com.bifrost.common.constant.SessionConstant;
import com.bifrost.common.model.ResultModel;
import com.bifrost.constant.MerchantConfigurationType;
import com.bifrost.entity.Customer;
import com.bifrost.entity.CustomerType;
import com.bifrost.entity.MerchantConfiguration;
import com.bifrost.model.CustomerModel;
import com.bifrost.repository.DailySignInHistoryRepository;
import com.bifrost.repository.MerchantConfigurationRepository;
import com.bifrost.service.CouponService;
import com.bifrost.service.CustomerService;
import com.bifrost.service.MemberService;
import com.bifrost.service.StoreService;
import com.bifrost.util.HttpContextUtils;
import com.bifrost.util.TransformUtils;
import com.bifrost.wechat.entity.WechatAccount;
import com.bifrost.wechat.service.WechatAccountService;
import com.bifrost.wechat.service.WxServiceContext;
import com.google.common.collect.Lists;
import me.chanjar.weixin.mp.api.WxMpService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 *会员中心相关接口
 *@author joewee
 *@version 1.0.0
 *@Date 2018/4/19 15:57
 */
@Controller
@RequestMapping("/api/customer")
public class CustomerCenterController {
    private static final Logger LOGGER=LoggerFactory.getLogger(CustomerCenterController.class);
    @Value("${wechat.oauth2.redirect.url:#{null}}")
    private String redirect_url;
    private static final String URL="/User/Card";
    @Autowired
    MemberService memberService;
    @Autowired
    WxServiceContext wxServiceContext;
    @Autowired
    WechatAccountService accountService;
    @Autowired
    CustomerService customerService;
    @Autowired
    StoreService storeService;
    @Autowired
    CouponService couponService;
    @Autowired
    DailySignInHistoryRepository historyRepository;
    @Autowired
    MerchantConfigurationRepository configurationRepository;
    @Autowired
    RedisTemplate<String,String> redis;

    @GetMapping("/center")
    public String center(@PathVariable Long store ){
        HttpServletResponse response = HttpContextUtils.getHttpServletResponse();
        WechatAccount account = accountService.getAccount(store);
        if(store==null||account==null){
            response.setStatus(404);
            return null;
        }
        HttpSession session  = HttpContextUtils.getHttpServletRequest().getSession();
        if(session.getAttribute(SessionConstant.OPEN_ID)!= null){
            return String.format("redirect:/index.html#%s",URL);
        }else{
            WxMpService wxService = wxServiceContext.getWxServiceByAppId(account.getAppId());
            String url = wxService.oauth2buildAuthorizationUrl(String.format("%s/%s",redirect_url,account.getAppId()), "snsapi_userinfo", String.format("/index.html%s%s","%23",URL));
            return "redirect:"+url;
        }

    }
    @Authorization
    @GetMapping("/loyalty")
    @ResponseBody
    public ResultModel getLoyaltyInfo(@CurrentUser Long userId){
        /*Customer user = customerService.findCustomer(userId);
        String unionid = user.getUnionId();
        JSONObject json = memberService.getMemberInfo(unionid);
        if(json.containsKey("errCode")&&json.getIntValue("errCode")==0){
            if (JSONPath.contains(json,"$.data.cardno")) {
                String cardNo =(String) JSONPath.eval(json,"$.data.cardno");
                if (!cardNo.equals(user.getLoyaltyCard()) && StringUtils.isNotBlank(cardNo)) {
                    if(JSONPath.contains(json,"$.data.username")){
                        user.setCustomerLastname(""+JSONPath.eval(json,"$.data.username"));
                    }
                    if(JSONPath.contains(json,"$.data.tel")){
                        user.setCustomerPhone(""+JSONPath.eval(json,"$.data.tel"));
                    }
                    customerService.bindLoyaltyCard(user,cardNo);
                }
                int count = couponService.countCoupons(user);
                CustomerType type = user.getCustomerType();
                if(type==null){
                    type = customerService.findDefaultCustomerType(user.getMerchantStore().getMerchantId());
                }
                return ResultModel.ok().put("bonusPoints",user.getBonusPoints())
                        .put("avatar",user.getMedia()==null?"":user.getMedia().getUrl())
                        .put("loyaltyNumber",cardNo)
                        .put("couponQuantity",count)
                        .put("customerName",user.getCustomerLastname())
                        .put("storeName",user.getMerchantStore().getStoreName())
                        .put("background",type==null?null:type.getBackground())
                        .put("logo",type==null?null:type.getLogo())
                        .put("other",type==null?null:type.getConfig());
            }
        }
        LOGGER.warn(unionid+":"+json.getString("errMessage"));
       return ResultModel.error("请绑定会员卡");*/
       return customerService.getLoyaltyInfo(userId);
    }
    @Authorization
    @GetMapping("/description")
    @ResponseBody
    public ResultModel getCustomerTypeDescription(@CurrentUser Long userId){
        Customer user = customerService.findCustomer(userId);
        CustomerType customerType = user.getCustomerType();
        if(customerType==null){
            customerType = customerService.findDefaultCustomerType(user.getMerchantStore().getMerchantId());
        }
        if(customerType !=null){
            return ResultModel.ok().put("description",customerType.getDescription());
        }
        return ResultModel.error("未找到相关信息");
    }
    /**
     * @param userId
     * @param method 注册时发送短信method=SendSmsCreate，ppid=0:用户未确认，ppid=3:用户已确认
     *               绑定时method=SendSmsBand，绑定发送短信成功则会员卡号在msg中：卡号,姓名,是否需要校验身份证|--|卡号,姓名,是否需要校验身份证
     * @param mobile
     * @param idNum
     * @param ppid
     * @return
     */
    @Authorization
    @PostMapping("/sendSms")
    @ResponseBody
    public ResultModel sendSms(@CurrentUser Long userId,@RequestParam String method,@RequestParam String mobile,@RequestParam String idNum,int ppid){
        Customer user = customerService.findCustomer(userId);
        String unionid = user.getUnionId();
        JSONObject json = memberService.sendSms(method,unionid,mobile,idNum,ppid);
        if(json.containsKey("ret")&&json.getIntValue("ret")==0){
            //绑卡发短信重新包装返回信息
            if("SendSmsBand".equalsIgnoreCase(method)){
                String[] cardInfos = json.getString("errmsg").split("\\|--\\|");
                List result = Lists.newArrayList();
                for (String cardInfo : cardInfos) {
                    Map map = new HashMap();
                    String[] info = cardInfo.split(",");
                    map.put("cardNum", info[0]);
                    map.put("name", info[1]);
                    if("Y".equalsIgnoreCase(info[2])){
                        map.put("flag", Boolean.TRUE);
                    }else{
                        map.put("flag", Boolean.FALSE);
                    }
                    result.add(map);
                }
                return ResultModel.ok().put("errmsg",result);
            }
            return ResultModel.ok(json.getString("errmsg"));
        //SendSmsCreate时需要用户确认:手机号也有会员卡信息，继续将冻结原会员卡
        }else if(json.containsKey("ret")&&json.getIntValue("ret")==9){
            return ResultModel.ok().put("flag",Boolean.TRUE).put("errmsg",json.getString("errmsg"));
        }
        return ResultModel.error(json.getString("errmsg"));
    }
    @Authorization
    @PostMapping("/register")
    @ResponseBody
    public ResultModel registerCRM(@CurrentUser Long user, @RequestParam String name, @RequestParam String mobile, @RequestParam String idNum, @RequestParam String verifyCode, @RequestParam int publicid, @RequestParam int ppid, @CurrentStore Long stroeId, @RequestParam(required = false) String userId){
        
        Boolean result = Boolean.TRUE;
        try {
            result = customerService.register(customerService.findCustomer(user),name,mobile,idNum,verifyCode,publicid,ppid,stroeId,userId);
            if(!result){
                return ResultModel.error("注册失败");
            }
            return ResultModel.ok("注册成功");
        }catch (Exception e){
            LOGGER.error("失败原因:",e);
            return ResultModel.error(e.getMessage());
        }
        /*Customer user = customerService.findCustomer(userId);
        String unionid = user.getUnionId();
        String method ="CreateCard";
        JSONObject json = memberService.register(method,unionid,name,mobile,idNum,verifyCode,publicid,ppid);
        if(json.containsKey("ret") && json.getIntValue("ret")==0){
            return ResultModel.ok(json.getString("errmsg"));
        }
        return ResultModel.error(json.getString("errmsg"));*/
    }
    @Authorization
    @PostMapping("/bind")
    @ResponseBody
    public ResultModel bind(@CurrentUser Long userId,@RequestParam String mobile,@RequestParam String idNum,@RequestParam String verifyCode,@RequestParam String cardno, int publicid,int ppid){
        /*Customer user = customerService.findCustomer(userId);
        String unionid = user.getUnionId();
        String method ="BindCard";
        JSONObject json = memberService.bind(method,unionid,mobile,idNum,verifyCode,cardno,publicid,ppid);
        if(json.containsKey("ret") && json.getIntValue("ret")==0){
            user.setIdentificationId(idNum);
            customerService.saveCustomer(user);
            return ResultModel.ok(json.getString("errmsg"));
        }
        return ResultModel.error(json.getString("errmsg"));*/
       return customerService.bind(userId,mobile,idNum,verifyCode,cardno,publicid,ppid);
    }
    @Authorization
    @GetMapping("/dynamicCardNumber")
    @ResponseBody
    public ResultModel dynamicCardNumber(@CurrentUser Long userId){
        Customer user = customerService.findCustomer(userId);
        String unionid = user.getUnionId();
        String dynamicCardNumber = memberService.getMemberCard(unionid);
        if(StringUtils.isNotBlank(dynamicCardNumber)){
            CustomerType customerType = user.getCustomerType();
            if(customerType==null){
                customerType = customerService.findDefaultCustomerType(user.getMerchantStore().getMerchantId());
            }
            return ResultModel.ok().put("cardNumber",dynamicCardNumber).put("description",customerType==null?null:customerType.getDescription())
                    .put("background",customerType==null?null:customerType.getBackground())
                    .put("logo",customerType==null?null:customerType.getLogo());
        }
        return ResultModel.error("获取动态会员码失败");
    }

    /**
     * 根据id返回customer明细
     * 该接口暂时只返回id和姓名，若有需要，请修改transformCustomerModel方法
     * @param id
     * @return
     */
    @GetMapping("/detail")
    @ResponseBody
    public ServerResponse detail(@RequestParam Long id){
        Customer customer = customerService.findCustomer(id);
        if(customer == null){
            return ServerResponse.createByErrorMsg("会员id有误");
        }
        CustomerModel customerModel = TransformUtils.transformToCustomerModel(customer);
        return ServerResponse.createBySuccess(customerModel);

    }

    /**
     * 每日签到详情
     * @param customerId
     * @return
     */
    @GetMapping("/signInDetail")
    @ResponseBody
    @Authorization
    public ResultModel signInDetail(@CurrentUser Long customerId , @CurrentStore Long storeId){
        //签到详情
        Customer customer = customerService.findCustomer(customerId);
        List list = customerService.signInDetail(customer);
        //最后签到日期 得到连续签到天数
        String count = redis.boundValueOps(String.format("persistenceSignIn:%s", customer.getOpenId())).get();
        //得到累计结束天数
        List<MerchantConfiguration> configurations = configurationRepository.findByMerchantStoreAndTypeDesc(storeId, MerchantConfigurationType.DAILY_SIGN_IN);

        return ResultModel.ok().put("data",list).put("persistenceDays",
                StringUtils.isNotBlank(count)?count:0)
                .put("msg",configurations.isEmpty()?"":String.format("温馨提示： 连续累计签到%s天，会进行重置累计天数。",configurations.get(0).getKey()));

    }

    /**
     *  每日签到
     * @param customerId
     * @param remark 签到心情备注
     * @return
     */
    @GetMapping("/signIn")
    @ResponseBody
    @Authorization
    public ServerResponse dailySignIn(@CurrentUser Long customerId ,@CurrentStore Long storeId, String remark){
        BigInteger bonusPoints = customerService.signIn(customerService.findCustomer(customerId),storeId,remark);
        return ServerResponse.createBySuccess();
    }

}
